package com.sample.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.sample.dao.TimeEntryDAO;
import com.sample.dao.UserProjectDAO;
import com.sample.model.Project;
import com.sample.model.TimeEntry;
import com.sample.model.UserProject;
import com.sample.service.TimeService;
import com.trg.search.flex.FlexSearch;
import com.trg.search.flex.FlexSearchWrapper;
import com.trg.search.Field;
import com.trg.search.Filter;
import com.trg.search.Search;
import com.trg.search.SearchUtil;

public class TimeServiceImpl implements TimeService {
	@Autowired
	private UserProjectDAO userProjectDAO;
	@Autowired
	private TimeEntryDAO timeEntryDAO;

	public void setUserProjectDAO(UserProjectDAO userProjectDAO) {
		this.userProjectDAO = userProjectDAO;
	}

	public void setTimeEntryDAO(TimeEntryDAO timeEntryDAO) {
		this.timeEntryDAO = timeEntryDAO;
	}

	public List<Project> fetchProjectsByUser(Long userID, Date rangeStart,
			Date rangeEnd) {
		Search s = new Search();
		s.addFilterEqual("user.id", userID);
		s.addFilterOr(Filter.isNull("startDate"), Filter.lessOrEqual("startDate", rangeEnd));
		s.addFilterOr(Filter.isNull("endDate"), Filter.greaterOrEqual("endDate", rangeStart));
		
		List<UserProject> userProjects = userProjectDAO.search(s);
		List<Project> projects = new ArrayList<Project>();

		for (UserProject userProject : userProjects) {
			projects.add(userProject.getProject());
		}

		return projects;
	}

	public List<TimeEntry> fetchTimeEntryByUser(Long userID, Date rangeStart,
			Date rangeEnd) {
		Search s = new Search();
		s.addFilterEqual("user.id", userID);
		s.addFilterGreaterOrEqual("date", rangeStart);
		s.addFilterLessOrEqual("date", rangeEnd);
		return timeEntryDAO.search(s);
	}

	public void batchUpdate(List<TimeEntry> update, List<TimeEntry> add,
			List<TimeEntry> delete) {
		if (update != null) {
			for (int i = 0; i < update.size(); i++) {
				if(update.get(i).getBillRate() == null || update.get(i).getBillRate().isNaN())
					update.get(i).setBillRate(null);
				timeEntryDAO.update(update.get(i));
			}
		}

		if (add != null) {
			for (int i = 0; i < add.size(); i++) {
				if(add.get(i).getBillRate() == null || add.get(i).getBillRate().isNaN())
					add.get(i).setBillRate(null);
				timeEntryDAO.create(add.get(i));
			}
		}

		if (delete != null) {
			for (int i = 0; i < delete.size(); i++) {
				if(delete.get(i).getBillRate() == null || delete.get(i).getBillRate().isNaN())
					delete.get(i).setBillRate(null);
				timeEntryDAO.deleteEntity(delete.get(i));
			}
		}
	}

	public Map<String, Object> searchTimeEntries(FlexSearch search) {
		Map<String, Object> result = new HashMap<String, Object>();
		FlexSearchWrapper wrapper = new FlexSearchWrapper(search);
		
		result.put("listResults", timeEntryDAO.searchAndCount(wrapper));
		Search s = SearchUtil.copy(wrapper, new Search());
		s.addField("hours", Field.OP_SUM);
		result.put("totalHours", timeEntryDAO.searchUnique(s));
		
		return result;
	}
}
